<?php
/*
 * @Author: lokei
 * @Date: 2023-03-19 12:13:49
 * @LastEditors: lokei
 * @LastEditTime: 2023-11-24 10:25:07
 * @Description: 
 */

namespace App\Common\Douyin;

use App\Models\Platform\Dy\Life\ConfModel;
use Exception;
use Illuminate\Support\Facades\Redis;

class Common
{
    public static function getAccessToken()
    {
        $redis_key = 'dy_smt_access_token';
        if (Redis::exists($redis_key)) {
            return Redis::get($redis_key);
        } else {
            $conf = ConfModel::first();
            if($conf == null) {
                return null;
            }
            $params = [
                'client_key' => $conf->appid,
                'client_secret' => $conf->secret,
                'grant_type' => 'client_credential'
            ];

            // 这里的参数需要使用raw的方式传参（！！！！这里需要注意）
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "https://open.douyin.com/oauth/client_token/");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            // curl_setopt($ch, CURLOPT_POSTFIELDS, $data); // 必须为字符串
            Common::curl_custom_postfields($ch, $params, array());  //这里是关键
            // curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data')); // 必须声明请求头 // 在上面curl_custom_postfields里面设置
            // 如果没有错误的话返回的就是小程序码的文件流
            $result_str = curl_exec($ch);
            $result = json_decode($result_str, true);
            Redis::setex($redis_key, intval($result['data']['expires_in']), $result['data']['access_token']);
            return $result['data']['access_token'];
        }
    }

    public static function curl_custom_postfields($ch, $assoc = array(), $files = array()) {
    
        // invalid characters for "name" and "filename"
        static $disallow = array("\0", "\"", "\r", "\n");
        
        // build normal parameters
        foreach ($assoc as $k => $v) {
            $k = str_replace($disallow, "_", $k);
            $body[] = implode("\r\n", array(
                "Content-Disposition: form-data; name=\"{$k}\"",
                "",
                filter_var($v), 
            ));
        }
        
        // build file parameters
        foreach ($files as $k => $v) {
        
            switch (true) {
                case false === $v = realpath(filter_var($v)):
                case !is_file($v):
                case !is_readable($v):
                    break; // or return false, throw new InvalidArgumentException
            }
            $data = file_get_contents($v);
            $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
            $k = str_replace($disallow, "_", $k);
            $v = str_replace($disallow, "_", $v);
            $body[] = implode("\r\n", array(
                "Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
                "Content-Type: image/jpeg",        //这里根据我自己需求修改的，貌似随便改别的也并不影响，起码贴图库不管
                "",
                $data, 
            ));
        }
        
        // generate safe boundary 
        do {
            $boundary = "---------------------" . md5(mt_rand() . microtime());
        } while (preg_grep("/{$boundary}/", $body));
        
        // add boundary for each parameters
        array_walk($body, function (&$part) use ($boundary) {
            $part = "--{$boundary}\r\n{$part}";
        });
        
        // add final boundary
        $body[] = "--{$boundary}--";
        $body[] = "";
        
        // set options
        return @curl_setopt_array($ch, array(
            CURLOPT_POST       => true,
            CURLOPT_POSTFIELDS => implode("\r\n", $body),
            CURLOPT_HTTPHEADER => array(
                "Expect: 100-continue",
                "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
            ),
        ));
    }

    /**
     * @param $access_token
     * @param $encrypted_data
     * @param null $code
     * @return mixed
     * 通过code 核销券码准备
     */
    public static function prepareCertificate($access_token, $encrypted_data, $code = null) {
        $url = 'https://open.douyin.com/goodlife/v1/fulfilment/certificate/prepare/';

        $params = [];
        if (!empty($encrypted_data)) {
            $params['encrypted_data'] = urlencode($encrypted_data);
        } elseif (!empty($code)) {
            $params['code'] = $code;
        } else {
            throw new Exception("encrypted_data 和 code 参数不能同时为空");
        }
        $back = Common::k_request($url,$params,$access_token,0);
        return $back;
    }

    /**
     * @param $verifyToken
     * @param $client_token
     * @param $poiId
     * @param $encryptedCodes
     * @param null $codes
     * @param null $orderId
     * @param null $codeWithTimeList
     * @param null $voucher
     * @return mixed
     */
    public static function verifyCoupon($verifyToken,$client_token, $poiId, $encryptedCodes, $codes = null, $orderId = null, $codeWithTimeList = null, $voucher = null) {
        $url = 'https://open.douyin.com/goodlife/v1/fulfilment/certificate/verify/';
        $data = array(
            'verify_token' => $verifyToken,
            'poi_id' => $poiId,
            'encrypted_codes' => $encryptedCodes,
            'codes' => $codes,
        );

        $response = Common::k_request($url,$data,$client_token);
        return $response;
    }


    /**
     * 抖音请求方法
     * @param $url
     * @param $client_token
     * @param array $data
     * @param int $is_post
     * @return mixed
     */
    public static function k_request($url,$data = [],$client_token = '',$is_post = 1){
        $headers = [
            'Content-Type: application/json',
            'access-token: ' . $client_token,
        ];
        $curl = curl_init();
        if($is_post){
            curl_setopt_array($curl, array(
                CURLOPT_URL => $url,
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_ENCODING => '',
                CURLOPT_CUSTOMREQUEST => 'POST',
                CURLOPT_POSTFIELDS => json_encode($data),
                CURLOPT_HTTPHEADER => $headers,
            ));
        }else{
            $data = http_build_query($data);
            curl_setopt_array($curl, [
                CURLOPT_URL => "$url?$data",
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_HTTPHEADER => $headers,
            ]);
        }
        $response = curl_exec($curl);
        curl_close($curl);
        return json_decode($response,true);
    }

}
